using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using dnAnalytics.Math;
using dnAnalytics.LinearAlgebra;
using dnAnalytics.Exceptions;

namespace dnAnalytics.UnitTests.LinearAlgebra
{
    [TestFixture]
    [Category("Managed")]
    public class MatrixBuilderTest
    {
        [Test]
        public void CreateIdentityMatrix()
        {
            Matrix matrix = MatrixBuilder.CreateIdentityMatrix(10);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    if (i == j)
                    {
                        Assert.AreEqual(1, matrix[i, j]);
                    }
                    else
                    {
                        Assert.AreEqual(0, matrix[i, j]);
                    }
                }

            }
        }

        [Test]
        public void CreateMatrixOrder()
        {
            Matrix matrix = MatrixBuilder.CreateMatrix(10);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }

            matrix = MatrixBuilder.CreateMatrix(10, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
        }

        [Test]
        public void CreateMatrixSize()
        {
            Matrix matrix = MatrixBuilder.CreateMatrix(10, 10);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 10, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 10, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 10, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 10, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 10, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(5, 10);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(5, 10, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(5, 10, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(5, 10, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(5, 10, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(5, 10, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 5);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 5, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 5, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 5, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 5, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            matrix = MatrixBuilder.CreateMatrix(10, 5, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
        }

        [Test]
        public void CreateMatrixValue()
        {
            Matrix matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }

            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 10, 5.5, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(5, 10, 5.5, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 5);
            Assert.AreEqual(matrix.Columns, 10);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }

            matrix = MatrixBuilder.CreateMatrix(10, 5, 5.5, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 10);
            Assert.AreEqual(matrix.Columns, 5);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < matrix.Rows; i++)
            {
                for (int j = 0; j < matrix.Columns; j++)
                {
                    Assert.AreEqual(5.5, matrix[i, j]);
                }
            }
        }


        [Test]
        public void CreateMatrixVector()
        {
            Vector vector = VectorBuilder.CreateVector(new double[] { 1, 2, 3, 4, 5 });

            Matrix matrix = MatrixBuilder.CreateMatrix(vector, false);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, true);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            if (Settings.DefaultMatrixType == MatrixType.Dense)
            {
                Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            }

            if (Settings.DefaultMatrixType == MatrixType.Sparse)
            {
                Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            }
            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, false, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, true, MatrixType.Dense);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, false, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, true, MatrixType.Sparse);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, false, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, true, MatrixType.Dense, true);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, false, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }


            matrix = MatrixBuilder.CreateMatrix(vector, true, MatrixType.Sparse, true);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, false, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, true, MatrixType.Dense, false);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, false, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, 1);
            Assert.AreEqual(matrix.Columns, vector.Count);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());

            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[0, i]);
            }

            matrix = MatrixBuilder.CreateMatrix(vector, true, MatrixType.Sparse, false);
            Assert.AreEqual(matrix.Rows, vector.Count);
            Assert.AreEqual(matrix.Columns, 1);
            Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
            for (int i = 0; i < vector.Count; i++)
            {
                Assert.AreEqual(vector[i], matrix[i, 0]);
            }
        }

        [Test]
        public void CreateMatrixArray()
        {
            Matrix orig = MatrixBuilder.CreateMatrix(10);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    orig[i, j] = (i + 1) / (i + j + 2);
                }
            }
            double[] array = orig.ToColumnWiseArray();
            Matrix test = MatrixBuilder.CreateMatrix(array, orig.Rows, orig.Columns, true);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    Assert.AreEqual(orig[i, j], test[i, j]);
                }
            }

            array = orig.ToRowWiseArray();
            test = MatrixBuilder.CreateMatrix(array, orig.Rows, orig.Columns, false);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    Assert.AreEqual(orig[i, j], test[i, j]);
                }
            }

            orig = MatrixBuilder.CreateMatrix(5,10);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    orig[i, j] = (i + 1) / (i + j + 2);
                }
            }
            array = orig.ToColumnWiseArray();
            test = MatrixBuilder.CreateMatrix(array, orig.Rows, orig.Columns, true);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    Assert.AreEqual(orig[i, j], test[i, j]);
                }
            }

            array = orig.ToRowWiseArray();
            test = MatrixBuilder.CreateMatrix(array, orig.Rows, orig.Columns, false);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    Assert.AreEqual(orig[i, j], test[i, j]);
                }
            }

            orig = MatrixBuilder.CreateMatrix(10, 5);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    orig[i, j] = (i + 1) / (i + j + 2);
                }
            }
            array = orig.ToColumnWiseArray();
            test = MatrixBuilder.CreateMatrix(array, orig.Rows, orig.Columns, true);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    Assert.AreEqual(orig[i, j], test[i, j]);
                }
            }

            array = orig.ToRowWiseArray();
            test = MatrixBuilder.CreateMatrix(array, orig.Rows, orig.Columns, false);
            for (int i = 0; i < orig.Rows; i++)
            {
                for (int j = 0; j < orig.Columns; j++)
                {
                    Assert.AreEqual(orig[i, j], test[i, j]);
                }
            }

        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CreateMatrixArrayNull()
        {
            double[] array = null;
            MatrixBuilder.CreateMatrix(array, 10, 10, true);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void CreateMatrixArrayLength()
        {
            double[] array = new double[10];
            MatrixBuilder.CreateMatrix(array, 10, 10, true);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CreateMatrixVectorNull()
        {
            Vector vector = null;
            MatrixBuilder.CreateMatrix(vector, true);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void CreateMatrixSizeNotPositive1()
        {
            MatrixBuilder.CreateMatrix(0, 2);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void CreateMatrixSizeNotPositive2()
        {
            MatrixBuilder.CreateMatrix(2, 0);
        }
    }
}
